import router from "@/router";
import asyncRoutes from "@/router/asyncRoutes";
import store from "@/store";

const WHITE_LIST = ["/login", "/404"];

// 切割权限信息
function getRoutepermissions(permissions, index) {
  const PermArr = permissions.map((item) => {
    const array = item.split(":");
    return index ? `${array[0]}:${array[1]}` : `${array[0]}`;
  });
  // 数组去重 [...new Set(数组)] 不能存重复的数据（去重），得到一个伪数组
  return Array.from(new Set(PermArr));
}

// 更具权限标识，过滤出有权路由表
function getRoutes(asyncRoutes, first, second) {
  // 判断是否为管理员（*）
  if (first.includes("*")) {
    return asyncRoutes;
  }
  // 当可读性差的时候就拆开写
  // const firstRoutes = asyncRoutes.filter((route) => first.includes(route.permission));
  // const secondRoutes = firstRoutes.map((item) => {
  //   return {
  // 在一级外层不变的情况下
  //     ...item,
  // 过滤 children 内的二级路由
  //     children: item.children.filter((child) => second.includes(child.permission)),
  //   };
  // });
  return asyncRoutes
    .filter((route) => {
      return first.includes(route.permission);
    })
    .map((item) => {
      return {
        ...item,
        children: item.children.filter((child) => second.includes(child.permission)),
      };
    });
  // 以一级路由为基础，过滤出二级路由
}

router.beforeEach(async (to, from, next) => {
  const token = store.state.user.token;
  if (token) {
    if (to.path === "/login") {
      next("/");
    } else {
      next();
      // 1.拿到用户权限信息
      // await store.dispatch("menu/getpermissions");
      const permissions = await store.dispatch("menu/getpermissions");
      // 2.根据权限标识，筛选对应路由信息
      const firstPermissions = getRoutepermissions(permissions, 0);
      const secondPermissions = getRoutepermissions(permissions, 1);
      // 3.根据一级权限标识和二级权限标识  对比 动态路由 进行筛选
      const routes = getRoutes(asyncRoutes, firstPermissions, secondPermissions);
      // 4.将动态路由表加入到路由系统中
      routes.forEach((route) => router.addRoute(route));
      // 5.江山选之后的落于添加到vuex中（渲染）
      store.commit("menu/setMenuList", routes);
    }
  } else {
    if (WHITE_LIST.includes(to.path)) {
      next();
    } else {
      next("/login");
    }
  }
});

// 组件中 this 指向vue实例，当通过 Vue.use(Vuex) 安装时，它会通过 Vue 的 混入(mixin)机制
// 自动在所有组件中注入 $store 属性。这是 Vue 插件系统的特性，可以直接this.$store....
// js文件中,没有 Vue 实例上下文,没有 this 指向组件实例 需要手动导入store实例

